<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport"
        content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta content='tms,chat,wiki,translation,blog,markdown,group,team,teamwork,聊天,沟通,知识库,博文,国际化翻译,团队协作' name='Keywords'>
    <meta content='TMS是免费开源的团队协作(团队沟通,博文知识库,国际化翻译i18n)web系统(响应式界面设计,移动端适配).' name='Description'>
    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <title>TMS博文</title>
    <!-- Include CSS for icons. -->
    <link href="cdn/font-awesome.min.css" rel="stylesheet" type="text/css" />
    <link href="cdn/codemirror.min.css" rel="stylesheet" type="text/css" />
    <link href="cdn/toastr.min.css" rel="stylesheet" type="text/css" />
    <link href="cdn/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />
    <link href="cdn/froala_style.min.css" rel="stylesheet" type="text/css" />
    <!-- jQuery Modal -->
    <link href="cdn/jquery.modal.min.css" rel="stylesheet" type="text/css" />
    <style>
        body {
            text-align: center;
        }

        div#editor {
            width: 75%;
            margin: auto;
            text-align: left;
            position: relative;
        }

        @media only screen and (max-width: 767px) {
            div#editor {
                width: 96%;
            }
        }

        .ss {
            background-color: red;
        }

        .fr-wrapper>div[style*='z-index: 9999'] {
            /*position: absolute;
        top: -10000px;
        opacity: 0;*/
            display: none;
        }

        .fr-placeholder {
            margin-top: 1px !important;
        }

        #toast-container {
            z-index: 9999999999 !important;
        }

        .topbar {
            position: absolute;
            top: -50px;
            width: 100%;
        }

        .topbar>input {
            /*width: 300px;*/
            width: 100%;
            font-size: 26px;
            box-sizing: border-box;
            /*box-shadow: none;*/
            outline: 0;
            border: 0;
            box-shadow: 0px 1px 0px 0px #dddddd;
            padding-right: 80px;
        }

        .topbar>.actions {
            right: 0;
            top: 0;
            position: absolute;
        }

        .topbar>.actions button {
            font-size: 12px;
        }

        #preview {
            display: none;
        }

        .blocker {
            z-index: 9999999999;
        }

        button.btn {
            color: #fff;
            background: #2185d0;
            padding: .5rem 1rem;
            display: inline-block;
            border-radius: 4px;
            transition-duration: .25s;
            border: none;
            font-size: 14px;
        }

        button.btn:hover {
            background: #1678c2;
        }

        #saveFrm .row {
            padding-bottom: 8px;
        }

        #saveFrm label {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        #saveFrm select {
            background: #fafdfe;
            height: 28px;
            width: 440px;
            margin-top: 3px;
            line-height: 28px;
            border: 1px solid #9bc0dd;
            -moz-border-radius: 2px;
            -webkit-border-radius: 2px;
        }

    </style>
</head>

<body>
    <div id="editor">
        <div class="topbar">
            <input id="title" type="text" placeholder="标题">
            <div class="actions">
                <button class="button -blue btn" id="save">保存</button>
                <button class="button -blue btn" id="preview">预览</button>
            </div>
            <span id="msg" style="color: red; padding-left: 16px;"></span>
        </div>
        <div id='edit' style="margin-top: 60px; padding-bottom: 60px;"></div>
    </div>
    <!-- Modal HTML embedded directly into document -->
    <div id="saveModal" class="modal">
        <div id="saveFrm" style="padding-top: 16px;">
            <div class="row">
                <label>选择空间</label>
                <select name="space"></select>
            </div>
            <div class="row">
                <label>选择分类</label>
                <select name="dir"></select>
            </div>
            <div class="row">
                <input id="privated" type="checkbox">
                <label for="privated">私有博文（不公开）</label>
            </div>
            <div class="row" style="padding-top: 16px;">
                <button class="btnOk btn">确定</button>
            </div>
        </div>
    </div>
    <div id="word2html-dropzone" style="display: none;"></div>
    <!-- <p><a href="#saveModal" rel="modal:open">Open Modal</a></p> -->
    <!-- Include jQuery lib. -->
    <script type="text/javascript" src="cdn/jquery.min.js"></script>
    <script type="text/javascript" src="cdn/codemirror.min.js"></script>
    <script type="text/javascript" src="cdn/xml.min.js"></script>
    <script type="text/javascript" src="cdn/toastr.min.js"></script>
    <script type="text/javascript" src="cdn/url.min.js"></script>
    <script type="text/javascript" src="cdn/jquery.modal.min.js"></script>
    <script type="text/javascript" src="cdn/lodash.core.min.js"></script>
    <!-- <script type="text/javascript" src="cdn/diff.min.js"></script> -->
    <script type="text/javascript" src="cdn/dropzone.min.js"></script>
    <script type="text/javascript" src="cdn/sockjs.min.js"></script>
    <script type="text/javascript" src="cdn/stomp.min.js"></script>
    <!-- Include Editor JS files. -->
    <script type="text/javascript" src="cdn/froala_editor.pkgd.min.js"></script>
    <script>
        var taskItemHtml =
            '<input data-id="$id" class="tms-task-item" style="margin:0; width:21px;" type="checkbox" />';

        var blog = null;
        var comment = null;

        $(function () {

            // toastr弹出消息提示插件全局配置设置
            toastr.options.positionClass = 'toast-bottom-center';
            toastr.options.preventDuplicates = true;

            $.FroalaEditor.DefineIcon('save', {
                NAME: 'save'
            });
            $.FroalaEditor.RegisterCommand('save', {
                title: '保存 (ctrl+shift+s)',
                focus: false,
                undo: false,
                refreshAfterCallback: false,
                callback: function () {
                    $('#save').click();
                }
            });
            $.FroalaEditor.DefineIcon('word2html', {
                NAME: 'file-word-o'
            });
            $.FroalaEditor.RegisterCommand('word2html', {
                title: '基于Word文档导入',
                focus: false,
                undo: false,
                refreshAfterCallback: false,
                callback: function () {
                    $('#word2html-dropzone').click();
                }
            });
            $.FroalaEditor.DefineIcon('task', {
                NAME: 'check-square-o'
            });
            $.FroalaEditor.RegisterCommand('task', {
                title: '任务列表 (ctrl+alt+t)',
                focus: false,
                undo: true,
                refreshAfterCallback: false,
                callback: taskHandler
            });

            $('#edit').on('click', 'input.tms-task-item', function (evt) {
                // console.log(evt);
                $(evt.currentTarget).attr("checked", $(evt.currentTarget).is(':checked'));
            });

            var uploadMaxFileSize = +(localStorage && localStorage.getItem(`tms-upload-max-file-size`));

            $('#word2html-dropzone').dropzone({
                url: "/admin/file/upload/word2html",
                paramName: 'file',
                clickable: true,
                dictDefaultMessage: '',
                maxFilesize: uploadMaxFileSize || 10,
                acceptedFiles: '.doc,.docx',
                init: function () {
                    this.on("sending", function (file, xhr, formData) {

                    });
                    this.on("success", function (file, data) {
                        if (data.success) {
                            $('#edit').froalaEditor('html.set', data.data.html);

                            if (!$('#title').val() && data.data.file && data.data.file
                                .name) {
                                var index = data.data.file.name.lastIndexOf('.');
                                $('#title').val(data.data.file.name.substring(0, index));
                            }
                        } else {
                            toastr.error(data.data, 'Word导入失败!');
                        }

                    });
                    this.on("error", function (file, errorMessage, xhr) {
                        toastr.error(errorMessage, 'Word导入失败!');
                    });
                    this.on("complete", function (file) {
                        this.removeFile(file);
                    });
                }
            });

            $('#edit').froalaEditor({
                    // toolbarBottom: true,
                    toolbarButtons: ['fullscreen', 'bold', 'italic', 'underline', 'strikeThrough',
                        'subscript', 'superscript', 'fontFamily', 'fontSize', '|', 'color',
                        'inlineStyle', 'paragraphStyle', '|', 'paragraphFormat', 'align', 'formatOL',
                        'formatUL', 'outdent', 'indent', '-', 'save', '|', 'word2html', 'task',
                        'insertLink',
                        'insertImage', 'insertVideo', 'insertFile', 'insertTable', 'emoticons',
                        'specialCharacters', '|', 'quote', 'insertHR', 'undo', 'redo',
                        'clearFormatting', 'selectAll', 'print', 'help', 'html'
                    ],
                    fontFamily: {
                        '宋体,SimSun,sans-serif': '宋体',
                        "微软雅黑,'Microsoft YaHein',sans-serif": '微软雅黑',
                        '楷体,楷体_GB2312,SimKai,sans-serif': '楷体',
                        '黑体,SimHei,sans-serif': '黑体',
                        '隶书,SimLi,sans-serif': '隶书',
                        "'andale mono',sans-serif": 'Andale Mono',
                        'Arial,Helvetica,sans-serif': 'Arial',
                        "'arial black','avant garde',sans-serif": 'Arial Black',
                        'Georgia,serif': 'Georgia',
                        "'comic sans ms',sans-serif": 'Comic Sans Ms',
                        'Impact,Charcoal,sans-serif': 'Impact',
                        'Tahoma,Geneva,sans-serif': 'Tahoma',
                        "'Times New Roman',Times,serif": 'Times New Roman',
                        'Verdana,Geneva,sans-serif': 'Verdana'
                    },
                    fontFamilySelection: true,
                    fontSizeSelection: true,
                    paragraphFormatSelection: true,
                    wordPasteModal: true,
                    formEditButtons: [], // 禁用表单编辑插件
                    // enter: $.FroalaEditor.ENTER_BR,
                    enter: $.FroalaEditor.ENTER_DIV,
                    language: 'zh_cn',
                    fileMaxSize: 1024 * 1024 * (uploadMaxFileSize || 10),
                    imageUploadURL: '/admin/file/upload/img',
                    imageUploadParams: {
                        toType: 'Blog',
                        baseUrl: getBaseUrl()
                    },
                    fileUploadURL: '/admin/file/upload/file',
                    fileUploadParams: {
                        toType: 'Blog',
                        baseUrl: getBaseUrl()
                    },
                    imageManagerLoadURL: '/admin/file/upload/img/list',
                    imageManagerDeleteURL: "/admin/file/upload/img/remove",
                    imageManagerDeleteMethod: "POST"
                }) // Catch image removal from the editor.
                .on('froalaEditor.image.removed', function (e, editor, $img) {
                    $.ajax({
                            method: "POST",
                            url: "/admin/file/upload/img/remove",
                            data: {
                                src: $img.attr('src')
                            }
                        })
                        .done(function (data) {
                            console.log('image was deleted');
                            // toastr && toastr.success('图片删除成功！');
                        })
                        .fail(function (err) {
                            console.log('image delete problem: ' + JSON.stringify(err));
                            toastr && toastr.error(JSON.stringify(err), '图片删除失败！');
                        });
                })
                .on('froalaEditor.file.beforeUpload', function (e, editor, file) {
                    if (editor.opts.fileUploadParams) {
                        editor.opts.fileUploadParams.atId = getAtId();
                    }
                })
                .on('froalaEditor.image.beforeUpload', function (e, editor, img) {
                    if (editor.opts.imageUploadParams) {
                        editor.opts.imageUploadParams.atId = getAtId();
                    }
                })
                // Catch image removal from the editor.
                .on('froalaEditor.file.unlink', function (e, editor, link) {
                    $.ajax({
                            method: "POST",
                            url: "/admin/file/upload/file/remove",
                            data: {
                                src: link.getAttribute('href')
                            }
                        })
                        .done(function (data) {
                            console.log('file was deleted');
                            // toastr && toastr.success('文件删除成功！');
                        })
                        .fail(function (err) {
                            console.log('file delete problem: ' + JSON.stringify(err));
                            toastr && toastr.error(JSON.stringify(err), '文件删除失败！');
                        });
                }).on('froalaEditor.keydown', function (e, editor, keydownEvent) {
                    console.log(keydownEvent);
                    if ((keydownEvent.ctrlKey || keydownEvent.metaKey) && keydownEvent.shiftKey &&
                        keydownEvent.keyCode === 83) { // ctrl+shift+s
                        $('#save').click();
                    } else if ((keydownEvent.ctrlKey || keydownEvent.metaKey) && keydownEvent.altKey &&
                        keydownEvent.keyCode === 84) { // ctrl+alt+t
                        taskHandler();
                    } else if (keydownEvent.keyCode === 13) {

                        var sbs = $('#edit').froalaEditor('selection.blocks');
                        if (sbs && sbs.length > 0) {
                            var $pre = $(sbs[0]).prev();
                            var $item = $pre.children('input.tms-task-item');

                            if ($item.size() === 1) {
                                if ($.trim($pre.text())) {
                                    $('#edit').froalaEditor('html.insert', taskId());
                                } else {
                                    $('#edit').froalaEditor('cursor.backspace');
                                    $('#edit').froalaEditor('cursor.backspace');
                                    // $('#edit').froalaEditor('cursor.backspace');
                                    // $('#edit').froalaEditor('cursor.backspace');
                                }
                            }
                        }

                        // console.log($('#edit').froalaEditor('selection.blocks'));
                        // console.log($('#edit').froalaEditor('selection.element'));
                        // console.log($('#edit').froalaEditor('selection.endElement'));
                        // console.log($('#edit').froalaEditor('selection.get'));
                    }
                });

            var isComment = typeof url('?comment') !== 'undefined';
            var id = url('?id');

            if (isComment) { // comment

                $('#title').hide();

                var cid = url('?cid');

                if (cid) {
                    $.get('/admin/blog/comment/get', {
                        cid: cid
                    }, function (data) {
                        if (data.success) {
                            comment = data.data;

                            $('#edit').froalaEditor('html.set', data.data.content);
                        } else {
                            toastr.error(data.data);
                        }
                    });
                }

                $('#save').click(function (event) {

                    var content = $('#edit').froalaEditor('html.get', true);

                    if (!content || !$.trim(content)) {
                        toastr && toastr.error('博文评论内容不能为空！');
                        return;
                    }

                    if (comment == null) {

                        window.bc_uuid = window.bc_uuid || uuid();

                        $.post('/admin/blog/comment/create', {
                            basePath: window.location.protocol + '//' + window.location.host +
                                '/page/index.html',
                            id: id,
                            editor: 'Html',
                            uuid: window.bc_uuid,
                            content: content
                        }, function (data, textStatus, xhr) {
                            if (data.success) {
                                window.bc_uuid = uuid();
                                comment = data.data;
                                toastr && toastr.success('博文评论保存成功！');
                                (window.parent && window.parent.postMessage) && (window.parent
                                    .postMessage({
                                        action: 'created',
                                        source: 'comment',
                                        comment: data.data,
                                        editor: 'html'
                                    }, window.location.origin));
                            } else {
                                toastr && toastr.error(data.data);
                            }
                        }).fail(function () {
                            toastr && toastr.error('网络传输错误！');
                        });
                    } else {
                        $.post('/admin/blog/comment/update', {
                            basePath: window.location.protocol + '//' + window.location.host +
                                '/page/index.html',
                            id: id,
                            cid: cid,
                            version: comment.version,
                            content: content
                        }, function (data, textStatus, xhr) {
                            if (data.success) {
                                comment = data.data;
                                toastr && toastr.success('博文评论保存成功！');
                                (window.parent && window.parent.postMessage) && (window.parent
                                    .postMessage({
                                        action: 'updated',
                                        source: 'comment',
                                        comment: data.data,
                                        editor: 'html'
                                    }, window.location.origin));
                            } else {
                                toastr && toastr.error(data.data);
                            }
                        }).fail(function () {
                            toastr && toastr.error('网络传输错误！');
                        });
                    }
                });

                window.addEventListener && window.addEventListener('message', (evt) => {

                    if (evt.origin != window.location.origin) return;

                    if (evt.data.source != 'blogClose') return;

                    if (evt.data.action == 'isUpdated') {

                        var updated = false;

                        var content = $('#edit').froalaEditor('html.get', true);

                        if (comment) {
                            updated = comment.content != content;
                        } else {
                            updated = !!$.trim(content);
                        }

                        (window.parent && window.parent.postMessage) && (window.parent
                            .postMessage({
                                action: 'isUpdated',
                                source: 'blogCloseAck',
                                item: evt.data.item,
                                updated: updated
                            }, window.location.origin));
                    }

                }, false);

            } else { // blog

                if (id) {
                    $.get('/admin/blog/get', {
                        id: id,
                        inc: false
                    }, function (data) {
                        if (data.success) {
                            if (typeof url('?copy') === 'undefined') { // edit
                                blog = data.data;
                                $('#title').val(data.data.title);

                                window.stompClient = Stomp.over(new SockJS('/ws-lock?blogId=' + blog
                                    .id));
                                window.stompClient.debug = function () {};
                                // this.stompClient.debug = function (msg) { console.log(msg) };
                                window.stompClient.connect({}, function (frame) {}, function (err) {
                                    console.error(err);
                                });

                            } else {
                                $('#title').val(data.data.title + ' (副本)');
                            }

                            $('#edit').froalaEditor('html.set', data.data.content);
                            $('#preview').show();
                        } else {
                            toastr.error(data.data);
                        }
                    });
                }


                $('#preview').click(function (event) {
                    var url = window.location.protocol + "//" + window.location.host + window.location
                        .pathname.replace('blog.html', 'index.html') + "#/blog/" + blog.id;
                    openNewWin(url);
                });

                // 博文保存选择，空间 + 分类
                var spaces = [];

                $('#saveFrm select[name="space"]').change(function (event) {
                    var sid = $(this).val();
                    $('#saveFrm select[name="dir"]').empty().append($('<option/>').text('(不指定分类)').attr(
                        'value', ''));

                    if (sid !== '') {
                        $.each(spaces, function (index, space) {
                            if (space.id == sid) {
                                window._ && (space.dirs = _.sortBy(space.dirs, 'name'));
                                $.each(space.dirs, function (index, dir) {
                                    if (dir.status != 'Deleted') {
                                        $('#saveFrm select[name="dir"]').append($(
                                            '<option/>').text(dir.name).attr(
                                            'value', dir.id));
                                    }
                                });

                                var did = localStorage && localStorage.getItem(
                                    'tms-blog-html-dir');
                                if (_.some(space.dirs, {
                                        id: +did
                                    })) {
                                    $('#saveFrm select[name="dir"]').val(did);
                                }

                                return false;
                            }
                        });
                    }
                });


                window.addEventListener && window.addEventListener('message', (evt) => {

                    if (evt.origin != window.location.origin) return;

                    if (evt.data.source != 'blogClose') return;

                    if (evt.data.action == 'isUpdated') {

                        var updated = false;

                        var title = $('#title').val();
                        var content = $('#edit').froalaEditor('html.get', true);

                        if (blog) {
                            updated = (blog.title != title) || (blog.content != content);
                        } else {
                            updated = !!$.trim(title) || !!$.trim(content);
                        }

                        (window.parent && window.parent.postMessage) && (window.parent
                            .postMessage({
                                action: 'isUpdated',
                                source: 'blogCloseAck',
                                item: evt.data.item,
                                updated: updated
                            }, window.location.origin));
                    }

                }, false);

                $('#save').click(function (event) {

                    var title = $('#title').val();
                    var content = $('#edit').froalaEditor('html.get', true);

                    if (!title || !$.trim(title)) {
                        toastr && toastr.error('博文标题不能为空！');
                        return;
                    }

                    if (!content || !$.trim(content)) {
                        toastr && toastr.error('博文内容不能为空！');
                        return;
                    }

                    if (blog == null) {
                        $.get('/admin/space/listMy', function (data) {
                            if (data.success) {

                                spaces = data.data;

                                $('#saveFrm select[name="space"]').empty().append($('<option/>')
                                    .text('(不指定空间)').attr('value', ''));
                                $('#saveFrm select[name="dir"]').empty().append($('<option/>')
                                    .text(
                                        '(不指定分类)').attr('value', ''));

                                window._ && (spaces = _.sortBy(spaces, 'name'));
                                $.each(spaces, function (index, space) {
                                    $('#saveFrm select[name="space"]').append($(
                                            '<option/>')
                                        .text(space.name).attr('value', space.id));
                                });

                                var sid = localStorage && localStorage.getItem(
                                    'tms-blog-html-space');
                                if (_.some(spaces, {
                                        id: +sid
                                    })) {
                                    $('#saveFrm select[name="space"]').val(sid);
                                    $('#saveFrm select[name="space"]').change();
                                }

                                var privated = localStorage && localStorage.getItem(
                                    'tms-blog-html-privated');

                                $('#privated').prop("checked", privated == 'true');

                                $('#saveModal').modal({
                                    fadeDuration: 200,
                                    clickClose: false
                                });

                            }
                        });
                    } else {
                        $.post('/admin/blog/update', {
                            url: window.location.protocol + '//' + window.location.host +
                                '/page/index.html',
                            id: blog.id,
                            version: blog.version,
                            // usernames: '',
                            // diff: diffS(blog.content, content),
                            title: title,
                            content: content
                        }, function (data, textStatus, xhr) {
                            if (data.success) {
                                blog = data.data;
                                toastr && toastr.success('博文更新成功！');
                                (window.parent && window.parent.postMessage) && (window.parent
                                    .postMessage({
                                        action: 'updated',
                                        autoFollow: true,
                                        source: 'blog',
                                        blog: data.data
                                    }, window.location.origin));
                            } else {
                                toastr && toastr.error(data.data);
                            }
                        }).fail(function () {
                            toastr && toastr.error('网络传输错误！');
                        });
                    }
                });

                $('#saveFrm .btnOk').click(function (event) {

                    var title = $('#title').val();
                    var content = $('#edit').froalaEditor('html.get', true);

                    if (!title || !$.trim(title)) {
                        toastr && toastr.error('博文标题不能为空！');
                        return;
                    }

                    if (!content || !$.trim(content)) {
                        toastr && toastr.error('博文内容不能为空！');
                        return;
                    }

                    if (blog == null) {

                        $.modal.close();

                        localStorage && localStorage.setItem('tms-blog-html-space', $(
                            '#saveFrm select[name="space"]').val());
                        localStorage && localStorage.setItem('tms-blog-html-dir', $(
                            '#saveFrm select[name="dir"]').val());
                        localStorage && localStorage.setItem('tms-blog-html-privated', $('#privated')
                            .prop(
                                "checked"));

                        window.b_uuid = window.b_uuid || uuid();

                        $.post('/admin/blog/create', {
                            url: window.location.protocol + '//' + window.location.host +
                                '/page/index.html',
                            // usernames: '',
                            spaceId: $('#saveFrm select[name="space"]').val(),
                            dirId: $('#saveFrm select[name="dir"]').val(),
                            title: title,
                            content: content,
                            editor: 'Html',
                            privated: $('#privated').prop("checked"),
                            uuid: window.b_uuid,
                            contentHtml: content
                        }, function (data, textStatus, xhr) {
                            if (data.success) {
                                window.b_uuid = uuid();
                                blog = data.data;
                                toastr && toastr.success('博文保存成功！');
                                $('#preview').show();
                                (window.parent && window.parent.postMessage) && (window.parent
                                    .postMessage({
                                        action: 'created',
                                        source: 'blog',
                                        blog: data.data,
                                        editor: 'html'
                                    }, window.location.origin));
                            } else {
                                toastr && toastr.error(data.data);
                            }
                        }).fail(function () {
                            toastr && toastr.error('网络传输错误！');
                        });
                    }
                });

                $('#title').keyup(function (e) {
                    if (e.keyCode === 13) {
                        $('#edit').froalaEditor('events.focus');
                    }
                });
            }
        });

        function taskHandler() {

            var sbs = $('#edit').froalaEditor('selection.blocks');

            _.each(sbs, function (e, i) {
                $item = $(e).children('.tms-task-item');
                if ($item.size() === 1) {
                    $item.remove();
                } else {
                    if ($(e).text() || sbs.length > 1) {
                        $(e).prepend(taskId());
                    } else {
                        $('#edit').froalaEditor('html.insert', taskId());
                    }
                }
            });

            // console.log($('#edit').froalaEditor('selection.blocks'));
            // console.log($('#edit').froalaEditor('selection.element'));
            // console.log($('#edit').froalaEditor('selection.endElement'));
            // console.log($('#edit').froalaEditor('selection.get'));
        }

        var _index = 0;

        function taskId() {
            return taskItemHtml.replace('$id', new Date().getTime() + '-' + (_index++));
        }

        function openNewWin(url) {

            if (url) {
                var $a = $('<a href="' + url + '" target="_blank" style="display:none;"></a>').appendTo('body').end();
                $('<input type="button">').appendTo($a).end().click();

                setTimeout(function () {
                    $a.remove();
                }, 200);
            }

        }

        // 生成uuid
        function uuid() {
            var d = new Date().getTime();
            var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            return uuid;
        }

        function getBaseUrl() {
            return window.location.protocol + '//' + window.location.host;
        }

        function getAtId() {

            var isComment = typeof url('?comment') !== 'undefined';
            if (isComment) {
                if (comment) {
                    return comment.uuid;
                } else {
                    window.bc_uuid = window.bc_uuid || uuid();
                    return window.bc_uuid;
                }
            } else {
                if (blog) {
                    return blog.uuid;
                } else {
                    window.b_uuid = window.b_uuid || uuid();
                    return window.b_uuid;
                }
            }

            return window.location.protocol + '//' + window.location.host;
        }

        /**
         * 文本比较
         * @param  {[type]} oldS [description]
         * @param  {[type]} newS [description]
         * @return {[type]}      [description]
         */
        function diffS(oldS, newS, way) {
            var ways = ['diffChars', 'diffWords', 'diffWordsWithSpace', 'diffLines'];
            if (!ways.includes(way)) {
                way = 'diffWords';
            }
            var delStyle = 'style="background-color: #e6cf56; text-decoration: line-through;"';
            var insStyle = 'style="background-color: #98e287; text-decoration: none;"';
            var diff = JsDiff[way](oldS, newS);
            var nodeArr = [];
            for (var i = 0; i < diff.length; i++) {

                if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
                    var swap = diff[i];
                    diff[i] = diff[i + 1];
                    diff[i + 1] = swap;
                }

                var node;
                if (diff[i].removed) {
                    node = '<del ' + delStyle + '>' + diff[i].value + '</del>';
                } else if (diff[i].added) {
                    node = '<ins ' + insStyle + '>' + diff[i].value + '</ins>';
                } else {
                    node = diff[i].value;
                }
                nodeArr.push(node);
            }

            return '<pre>' + nodeArr.join('') + '</pre>';
        }

    </script>
</body>

</html>
